package com.dreammore.framework.common.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class Tools {

	private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

	private static final SimpleDateFormat LONG_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private static final SimpleDateFormat LONGDATEFORMAT = new SimpleDateFormat("yyyyMMddHHmmss");

	/**
	 * 列表转换为数组
	 * 
	 * @param srcs
	 * @param dests
	 *                空的数组
	 */
	public static <T> void list2Array(List<T> srcs, T[] dests) {
		for (int i = 0, length = srcs.size(); i < length; i++) {
			dests[i] = srcs.get(i);
		}
	}

	/**
	 * 数组转换为列表
	 * 
	 * @param srcs
	 * @param dests
	 *                空的列表
	 */
	public static <T> void array2List(T[] srcs, List<T> dests) {
		for (T src : srcs) {
			dests.add(src);
		}
	}

	/**
	 * 是否null 或者 “”
	 * 
	 * @return
	 */
	public static boolean empty(String target) {
		if (target == null || "".equals(target) || "null".equals(target)) {
			return true;
		}

		return false;

	}

	public static <T> boolean empty(T target) {
		if (target == null) {
			return true;
		}
		return false;
	}

	/**
	 * 是否null 或者 empty
	 * 
	 * @param target
	 * @return
	 */
	public static <T> boolean empty(List<T> target) {
		if (target == null || target.isEmpty()) {
			return true;
		}
		return false;
	}

	public static <K, V> boolean empty(Map<K, V> target) {
		if (target == null || target.isEmpty()) {
			return true;
		}
		return false;
	}

	public static <T> boolean empty(T[] target) {
		if (target == null || target.length == 0) {
			return true;
		}
		return false;
	}

	public static String getDateString(Date date) {
		if (date == null) {
			return null;
		}
		return SIMPLE_DATE_FORMAT.format(date);
	}

	public static Date getDate(String dateString) {
		if (dateString == null) {
			return null;
		}
		try {
			return SIMPLE_DATE_FORMAT.parse(dateString);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	public static String getLongDateString(Date date) {
		if (date == null) {
			return null;
		}
		return LONG_DATE_FORMAT.format(date);
	}

	public static String getLongTimeString(Date date) {
		if (date == null) {
			return null;
		}
		return LONGDATEFORMAT.format(date);
	}

	public static Date getLongDate(String dateString) {
		if (dateString == null) {
			return null;
		}
		if (dateString.length() == 10) {
			dateString = dateString.concat(" 00:00:00");
		}
		try {
			return LONG_DATE_FORMAT.parse(dateString);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	public static Date getNowSimpleDate() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getFirstNowDate() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DATE, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getAfterNDate(Date nowDate, int n, int type) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(nowDate);
		if (type == Calendar.YEAR) {
			calendar.add(Calendar.YEAR, n);
		} else if (type == Calendar.MONTH) {
			calendar.add(Calendar.MONTH, n);
		} else if (type == Calendar.DATE) {
			calendar.add(Calendar.DATE, n);
		} else if (type == Calendar.HOUR_OF_DAY) {
			calendar.add(Calendar.HOUR_OF_DAY, n);
		} else if (type == Calendar.MINUTE) {
			calendar.add(Calendar.MINUTE, n);
		} else if (type == Calendar.SECOND) {
			calendar.add(Calendar.SECOND, n);
		} else {
			return nowDate;
		}
		return calendar.getTime();
	}

	public static Date getAfterNSimpleDate(Date nowDate, int n, int type) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(nowDate);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		if (type == Calendar.YEAR) {
			calendar.add(Calendar.YEAR, n);
		} else if (type == Calendar.MONTH) {
			calendar.add(Calendar.MONTH, n);
		} else if (type == Calendar.DATE) {
			calendar.add(Calendar.DATE, n);
		} else if (type == Calendar.HOUR_OF_DAY) {
			calendar.add(Calendar.HOUR_OF_DAY, n);
		} else if (type == Calendar.MINUTE) {
			calendar.add(Calendar.MINUTE, n);
		} else if (type == Calendar.SECOND) {
			calendar.add(Calendar.SECOND, n);
		} else {
			return nowDate;
		}
		return calendar.getTime();
	}

	public static <K, T> Map<K, T> inverseMap(Map<T, K> sourceMap) {
		Map<K, T> destMap = new HashMap<K, T>();
		Set<Entry<T, K>> tempSet = sourceMap.entrySet();
		for (Entry<T, K> entry : tempSet) {
			destMap.put(entry.getValue(), entry.getKey());
		}
		return destMap;
	}

	public static String whitespaceFormFull2Half(String input) {
		if (input == null) {
			return "";
		}
		char c[] = input.toCharArray();
		for (int i = 0; i < c.length; i++) {
			int d = c[i];
			if (d == 160) {
				c[i] = 0;
			}
		}

		return new String(c);
	}

	public static List<String> snatchDateString(String sourceString) {
		List<String> targets = new ArrayList<String>();
		Pattern pattern = Pattern.compile("[0-9]{4}[年|\\-|/][0-9]{1,2}[月|\\-|/][0-9]{1,2}");
		Matcher matcher = pattern.matcher(sourceString);
		while (matcher.find()) {
			if (!"".equals(matcher.group())) {
				String date = matcher.group();
				date = date.replaceAll("年", "-");
				date = date.replaceAll("月", "-");
				date = date.replaceAll("/", "-");
				targets.add(date);
			}
		}

		return targets;
	}

	public static <T> List<T> getEmptyList() {
		return new LinkedList<T>();
	}

	public static <T> List<T> add2List(T t, List<T> list) {
		list.add(t);
		return list;
	}

	/**
	 * 括号字符串
	 */
	public static String list2String(List<String> list) {
		StringBuilder sb = new StringBuilder();
		sb.append("(");
		for (String var : list) {
			sb.append("\"").append(var).append("\", ");
		}
		sb.delete(sb.length() - 2, sb.length());
		sb.append(")");
		return sb.toString();
	}

	/**
	 * 括号字符串
	 */
	public static String array2String(String[] array) {
		StringBuilder sb = new StringBuilder();
		sb.append("(");
		for (String var : array) {
			sb.append("\"").append(var).append("\", ");
		}
		sb.delete(sb.length() - 2, sb.length());
		sb.append(")");
		return sb.toString();
	}

	/**
	 * 逗号分隔字符串
	 */
	public static String list2Str(List<String> list) {
		if (empty(list)) {
			return "";
		}
		StringBuffer sb = new StringBuffer();
		for (String var : list) {
			sb.append(",").append(var);
		}
		return sb.toString().substring(1);
	}

	/**
	 * 逗号分隔字符串
	 */
	public static String array2Str(String[] array) {
		if (empty(array)) {
			return "";
		}
		StringBuffer sb = new StringBuffer();
		for (String var : array) {
			sb.append(",").append(var);
		}
		return sb.toString().substring(1);
	}

	public static String getShortTimeString(long timeMillis) {
		long time = timeMillis / 1000;
		long hours = time / 3600;
		long minutes = ((time - hours * 3600) / 60);
		long seconds = time % 60;

		String template = "%02d:%02d:%02d";
		return String.format(template, hours, minutes, seconds);
	}

	// public static void main(String[] args) {
	// String str =
	// "本页面最后修订于2012年2月14日 (星期二) 2015-13/35日 11:29。2012-135/14<br /></li>";
	// System.out.println(snatchDateString(str));
	// }
	public static long getIntervalDays(Date date1, Date date2) {
		if (null == date1 || null == date2) {
			return -1;
		}
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
	        calendar.set(Calendar.MINUTE, 0);
	        calendar.set(Calendar.SECOND, 0);
	        calendar.set(Calendar.MILLISECOND, 0);

		long time1 = calendar.getTimeInMillis();
		
		calendar.setTime(date2);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
	        calendar.set(Calendar.MINUTE, 0);
	        calendar.set(Calendar.SECOND, 0);
	        calendar.set(Calendar.MILLISECOND, 0);
		long time2 = calendar.getTimeInMillis();

		long days = Math.abs((time1 - time2) / (24 * 60 * 60 * 1000));

		return days;
	}

	public static void main(String[] args) {
		// System.out.println(Tools.getLongDateString(Calendar.getInstance().getTime()));
		List<String> list = new ArrayList<String>();
		list.add("1");
		list.add("2");
		list.add("3");
		list.add("4");
		list.add("5");
		System.out.println(list2String(list));

		System.out.println(getNowSimpleDate());
		System.out.println(getAfterNDate(getNowSimpleDate(), 1, Calendar.DATE));

		System.out.println(getLongTimeString(new Date()));

		System.out.println(getShortTimeString(13456000));

		Date date1 = Tools.getLongDate("2016-11-05 23:59:59");
		Date date2 = Tools.getLongDate("2016-11-09 00:00:10");

		System.out.println(getIntervalDays(date1, date2));

	}

}
